MultiplayerEvents = {
    MOVE:"MOVE",
    PLANTBOMB:"PLANTBOMB",
    PLAYERJOIN:"PLAYERJOIN",
    STARTGAME:"STARTGAME",
    REMOVELIFE:"REMOVELIFE"
};

var interpretJoin = function (JSONmsg) {
    log("JOIN MESSAGE RECIEVED: ");
    log(JSONmsg);

    addJoinedPlayer(JSONmsg.playerUID);
    if (OurGame.isInitator) {
        log("isInitator");
        OurGame.curNrOfPlayers += 1;
        if (OurGame.curNrOfPlayers == OurGame.maxNrOfPlayers) {
            createSTARTButton();
        }
    }
};

var interpretPlant = function (JSONmsg) {
    var index = getElementIndexByTypeAndID(Number(JSONmsg.playerUID), "p");
//    log(index + "; " + JSONmsg.bombx + "-" + JSONmsg.bomby);
    OurGame.players[index].plantBomb(JSONmsg.bombx, JSONmsg.bomby);
};

var interpretMove = function (JSONmsg) {
//    log(JSONmsg.x_move + "-" + JSONmsg.y_move);
    var index = getElementIndexByTypeAndID(Number(JSONmsg.playerUID), "p");
    OurGame.players[index].x_move += JSONmsg.x_move;
    OurGame.players[index].y_move += JSONmsg.y_move;
};

var interpretStartGame = function (JSONmsg) {
    log("START GAME MESSAGE RECIEVED: ");
    log(JSONmsg);
    removeLobby();
    addGeneratedUpgrades(JSONmsg.upgrades);
    createMultiplayersAndStart(JSONmsg.players);
};

var interpretRemoveLife = function (JSONmsg) {
    var index = getElementIndexByTypeAndID(Number(JSONmsg.playerUID), "p");
    log("REMOVE LIFE");
    if (OurGame.players[index]) {
        OurGame.players[index].immortalTimer = 0;
        for (var i = 0; i < JSONmsg.playerLivesAndScores.length; i++){
            index = getElementIndexByTypeAndID(Number(JSONmsg.playerLivesAndScores[i].id), "p");
            if (OurGame.players[index] != undefined) {
                OurGame.players[index].lives = Number(JSONmsg.playerLivesAndScores[i].lives);
                OurGame.players[index].kills = Number(JSONmsg.playerLivesAndScores[i].kills);
                updatePlayerSidebar(OurGame.players[index]);
            }
        }
    }
};

function getGamesStat(callback) {
    jQuery.ajax({
        url:"/lobby/getGamesStat",
        success:function (data) {
            if (data.status == "FAILURE") {
                stickyError('An error occurred', "ERROR /lobby/getGamesStat: " + data.reason);
            } else {
                if (callback != undefined) {
                    callback(data);
                }
                else {
                    log(data);
                }
            }
        },
        error:function (data) {
            stickyError('An error occurred!', "Error /lobby/getGamesStat: " + data);
        },
        type:"get",
        timeout:30000
    });
}

function markUserOffline() {
    var data = {
        "playerUID":OurGame.UID
    };
    sendData("/user/markUserOffline", JSON.stringify(data));
}

function createOrMarkOnline() {
    var data = {
        "playerUID":OurGame.UID
    };
    sendData("/user/createOrMarkOnline", JSON.stringify(data));
}

function createFinalStates() {
    var finalStates = [];
    for (var i = 0; i < OurGame.deadPlayers.length; i++) {
        finalStates.push({"UID":OurGame.deadPlayers[i].id, "score":OurGame.deadPlayers[i].kills});
    }
    var j = getWinningPlayerIndex();
    finalStates.push({"UID":OurGame.players[j].id, "score":OurGame.players[j].kills});
    log(finalStates);
    return finalStates;
}
function getWinningPlayerIndex() {
    for (var i = 0; i < OurGame.players.length; i++) {
        if (OurGame.players[i]) {
            return i;
        }
    }
}
function gameOver() {
    var data = {
        "gameID":OurGame.gameID,
        "finalStates":createFinalStates()
    };
    sendData("/gameOver", JSON.stringify(data));
}

function getPlayerLivesAndScores() {
    var lives = [];
    for (var i = 0; i < OurGame.players.length; i++) {
        if (OurGame.players[i]) {
            lives.push({"id":OurGame.players[i].id, "lives":OurGame.players[i].lives, "kills":OurGame.players[i].kills});
        }
    }
    return lives;
}
function removeLife() {
    log("REMOVE LIFE DATA SENT");
    var data = {
        "gameID":OurGame.gameID,
        "socketID":OurGame.socketID,
        "playerUID":OurGame.UID,
        "playerLivesAndScores":getPlayerLivesAndScores()
    };
    if (channel.trigger("client-"+MultiplayerEvents.REMOVELIFE, JSON.stringify(data))) {
        log("Removed!");
    } else {
        stickyError('An error occured when syncing lives and scores!', "FUUUU");
    }
}

function makeMove(player) {
    var data = {
        "gameID":OurGame.gameID,
        "playerUID":OurGame.UID,
        "socketID":OurGame.socketID,
        "x_move":player.x_move,
        "y_move":player.y_move
    };

    PUBNUB.publish({             // SEND A MESSAGE.
        channel:OurGame.gameID + "-move",
        message:data
    });
}

function plantBomb(player) {
    var data = {
        "gameID":OurGame.gameID,
        "playerUID":OurGame.UID,
        "socketID":OurGame.socketID,
        "bombx":player.x,
        "bomby":player.y
    };
    if (channel.trigger("client-"+MultiplayerEvents.PLANTBOMB, JSON.stringify(data))) {
        log("plant");
    } else {
        stickyError('An error occured when planting bomb!', "FUUUU");
    }
}

function startGame() {
    $('#startButton').remove(); // remove start button so that user can't press it more than once
    var upgrades = generateUpgrades();
//    log(upgrades);
    var data = {
        "gameID":OurGame.gameID,
        "playerUIDs":OurGame.playerUIDs,
        "upgrades":upgrades
    };
    sendData("/startGame", JSON.stringify(data));
}

var registerPlayer = function (JSONmsg) {
    var uid = OurGame.UID;
    var gameID = OurGame.gameID;
    var register = {
        "gameID":gameID,
        "playerUID":uid,
        "socketID":OurGame.socketID
    };

    if (channel.trigger("client-"+MultiplayerEvents.PLAYERJOIN, JSON.stringify(register))) {
        log("register sent");
    } else {
        stickyError('An error occured when registering player!', "FUUUU");
    }
};

function checkJoinPermission(gameID) {
    var uid = OurGame.UID;

    OurGame.isInitator = false;
    var register = {
        "gameID":gameID,
        "playerUID":uid
    };

    var success = function (serverAns) {
        if (serverAns.status == "SUCCESS") {
            OurGame.nrOfPlayers = serverAns.nrOfPlayers;
            log("CECKJOIN");
            log('Server answer: ' + serverAns);

            startGameWaitScreen(serverAns.registeredPlayers, serverAns.itendedPlayers, serverAns.nrOfPlayers);
            initChannel();
        } else {
            stickyError('And error occured when checking game join permission!', "ERROR checkJoinPermission: " + serverAns.reason);
        }
    };
    sendData("/checkJoinPermission", JSON.stringify(register), success);
}

function initChannel() {

    // LISTEN FOR MESSAGES
    PUBNUB.subscribe({
        channel:OurGame.gameID + "-move", // CONNECT TO THIS CHANNEL.
        restore:true, // STAY CONNECTED, EVEN WHEN BROWSER IS CLOSED
        callback:function (message) { // RECEIVED A MESSAGE.
            if (message.playerUID != OurGame.UID) {
                interpretMove(message);
            }
        },
        disconnect:function () {        // LOST CONNECTION.
            log(
                "Connection Lost." +
                    "Will auto-reconnect when Online."
            );
        },
        reconnect:function () {        // CONNECTION RESTORED.
            log("PUBNUB: And we're Back!");
        },

        connect:function () {        // CONNECTION ESTABLISHED.
            log("PUBNUB CONNECTED");
        }
    });

    var pusher = new Pusher(OurGame.appKey);
    pusher.connection.bind('connected', function () {
        log("CONNECTED!");
        OurGame.socketID = pusher.connection.socket_id;
    });
    channel = pusher.subscribe("private-"+OurGame.gameID.toString());
    channel.bind('pusher:subscription_succeeded', registerPlayer);
    channel.bind("client-"+MultiplayerEvents.PLANTBOMB, interpretPlant);
    channel.bind("client-"+MultiplayerEvents.PLAYERJOIN, interpretJoin);
//    channel.bind(MultiplayerEvents.PLANTBOMB, interpretPlant);
    channel.bind("client-"+MultiplayerEvents.STARTGAME, interpretStartGame);
    channel.bind("client-"+MultiplayerEvents.REMOVELIFE, interpretRemoveLife);
}

function sendData(path, myData, successFunction, errorFunction) {
    jQuery.ajax({
        url:path,
        data:{"data":myData},
        success:successFunction || function (data) {
            if (data.status == "FAILURE") {
                alert("ERROR: " + data.reason);
            }
        },
        error:errorFunction || function (data) {
            log(data);
        },
        type:"post",
        timeout:30000
    });
}